﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tzeentch
{
    class Logger: IDisposable
    {
        System.IO.StreamWriter _logfile = null;
        int _elementHeaderAmount = 1;

        /// <summary>
        /// Initializes a new instance of the <see cref="Logger"/> class.
        /// </summary>
        public Logger()
        {
            // New guid for log file.
            // get guid

            string dir      = System.Windows.Forms.Application.StartupPath + "\\log";
            string filename = "log(" + System.Guid.NewGuid() + ").csv";            
            string fullPath = dir + "\\" + filename;

            if (!System.IO.Directory.Exists(dir))
                System.IO.Directory.CreateDirectory(dir);

            _logfile = new System.IO.StreamWriter(fullPath);
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            _logfile.Close();
            _logfile.Dispose();
        }

        /// <summary>
        /// Writes to log.
        /// </summary>
        /// <param name="line">The line.</param>
        public void WriteToLog(string line)
        {
            _logfile.WriteLine(line);
        }

        /// <summary>
        /// Writes to log.
        /// </summary>
        /// <param name="values">The values.</param>
        public void WriteToLog(List<string> values)
        {
            string result = null;
            for (int i = 0; i < values.Count(); ++i)
            {
                if (i != 0)
                    result += ";";
                result += values[i];
            }
            WriteToLog(result);
        }

        /// <summary>
        /// Sets the amount of element headers.
        /// </summary>
        /// <param name="amount">The amount.</param>
        public void SetAmountOfElementHeaders(int amount)
        {
            _elementHeaderAmount = amount;
            SetHeaders();
        }

        /// <summary>
        /// Sets the headers.
        /// </summary>
        private void SetHeaders()
        {
            List<string> headers = new List<string> { "Population", "MAX_F", "min_F", "Average_F", "Median_F" };
            for (int i = 0; i < _elementHeaderAmount; ++i)
                headers.Add("Fitness of " + (i+1));
            WriteToLog(headers);
        }

        /// <summary>
        /// Counts the logs.
        /// </summary>
        /// <param name="iterationNumber">The iteration number.</param>
        /// <param name="allValues">All values.</param>
        public void CountLogs(int iterationNumber, double[] allValues)
        {
            List<string> results = new List<string> { };

            // population
            results.Add(iterationNumber.ToString());

            Array.Sort(allValues);
            
            // max
            results.Add(allValues.Last().ToString());

            // min
            results.Add(allValues.First().ToString());

            // average
            {
                double average = 0;
                foreach (double d in allValues)
                {
                    average += d / allValues.Count();
                }
                results.Add(average.ToString());
            }

            // median
            {
                double median;
                median = allValues[allValues.Count() / 2];
                results.Add(median.ToString());
            }

            // add to results
            for (int i = allValues.Count() - 1; i >= 0; --i)
            {
                results.Add(allValues[i].ToString());
            }

            WriteToLog(results);
        }
    }
}
